package cn.iocoder.yudao.module.reading.service.community;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.reading.config.CommunitySecurityConfig;
import cn.iocoder.yudao.module.reading.controller.app.community.vo.common.SensitiveCheckRespVO;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.module.system.service.social.SocialClientService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import cn.binarywang.wx.miniapp.api.WxMaService;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.reading.enums.ErrorCodeConstants.*;

/**
 * 微信内容安全检查服务实现类
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class WxContentSecurityServiceImpl implements WxContentSecurityService {

    @Resource
    private SocialClientService socialClientService;

    @Resource
    private CommunitySecurityConfig securityConfig;

    @Resource
    private LocalSensitiveWordService localSensitiveWordService;

    @Override
    @Cacheable(value = "community:sensitive:text", key = "#content", condition = "@communitySecurityConfig.enableCache")
    public SensitiveCheckRespVO checkTextContent(String content) {
        if (StrUtil.isBlank(content)) {
            return buildSafeResult(content);
        }

        // 1. 先进行本地敏感词检查（快速过滤）
        if (securityConfig.getEnableLocalCheck()) {
            SensitiveCheckRespVO localResult = localSensitiveWordService.checkTextContent(content);
            if (localResult.getHasSensitive()) {
                log.info("[checkTextContent][本地敏感词检查发现违规内容] content: {}, words: {}",
                        content, localResult.getSensitiveWords());
                return localResult;
            }
        }

        // 2. 检查是否启用微信检查
        if (!securityConfig.getEnableWxCheck()) {
            log.debug("[checkTextContent][微信内容安全检查已禁用] content: {}", content);
            return buildSafeResult(content);
        }

        // 3. 调用微信内容安全检查API（暂时注释，等待API确认）
        try {
            // 获取微信小程序服务
            WxMaService wxMaService = socialClientService.getWxMaService(UserTypeEnum.MEMBER.getValue());

            // 调用微信内容安全检查API - 使用msgSecCheck接口（暂时注释）
            // boolean result = wxMaService.getSecCheckService().checkMessage(content);
            // return convertBooleanToSensitiveCheckResult(result, content);

            // 暂时返回安全结果
            return buildSafeResult(content);

        } catch (Exception e) {
            log.error("[checkTextContent][content({}) 内容安全检查异常]", content, e);
            return handleException(e, content);
        }
    }

    @Override
    @Cacheable(value = "community:sensitive:image", key = "#imageUrl", condition = "@communitySecurityConfig.enableCache")
    public SensitiveCheckRespVO checkImageContent(String imageUrl) {
        if (StrUtil.isBlank(imageUrl)) {
            return buildSafeResult("");
        }

        // 检查是否启用微信检查
        if (!securityConfig.getEnableWxCheck()) {
            log.debug("[checkImageContent][微信图片安全检查已禁用] imageUrl: {}", imageUrl);
            return buildSafeResult(imageUrl);
        }

        try {
            // 获取微信小程序服务
            WxMaService wxMaService = socialClientService.getWxMaService(UserTypeEnum.MEMBER.getValue());

            // 下载图片
            byte[] imageBytes = downloadImage(imageUrl);

            // 检查图片大小
            if (imageBytes.length > securityConfig.getMaxImageSize()) {
                log.warn("[checkImageContent][图片大小超过限制] imageUrl: {}, size: {}", imageUrl, imageBytes.length);
                throw exception(COMMUNITY_IMAGE_CHECK_FAILED, "图片大小超过限制");
            }

            // 调用微信图片内容安全检查API - 使用imgSecCheck接口（暂时注释）
            // boolean result = wxMaService.getSecCheckService()
            //         .checkImage(new ByteArrayInputStream(imageBytes));
            // return convertBooleanToSensitiveCheckResult(result, imageUrl);

            // 暂时返回安全结果
            return buildSafeResult(imageUrl);

        } catch (Exception e) {
            log.error("[checkImageContent][imageUrl({}) 图片安全检查异常]", imageUrl, e);
            return handleException(e, imageUrl);
        }
    }

    @Override
    public SensitiveCheckRespVO batchCheckTextContent(String... contents) {
        if (contents == null || contents.length == 0) {
            return buildSafeResult("");
        }

        List<String> sensitiveWords = new ArrayList<>();
        StringBuilder filteredContent = new StringBuilder();
        boolean hasSensitive = false;

        for (String content : contents) {
            if (StrUtil.isBlank(content)) {
                filteredContent.append(content);
                continue;
            }

            SensitiveCheckRespVO result = checkTextContent(content);
            if (result.getHasSensitive()) {
                hasSensitive = true;
                sensitiveWords.addAll(result.getSensitiveWords());
                filteredContent.append(result.getFilteredContent());
            } else {
                filteredContent.append(content);
            }
        }

        SensitiveCheckRespVO result = new SensitiveCheckRespVO();
        result.setHasSensitive(hasSensitive);
        result.setSensitiveWords(sensitiveWords);
        result.setFilteredContent(filteredContent.toString());
        return result;
    }

    /**
     * 转换微信检查结果为统一的响应格式（布尔值版本）
     */
    private SensitiveCheckRespVO convertBooleanToSensitiveCheckResult(boolean isSecure, String originalContent) {
        SensitiveCheckRespVO result = new SensitiveCheckRespVO();

        // 微信返回true表示内容安全，false表示有风险
        boolean hasSensitive = !isSecure;
        result.setHasSensitive(hasSensitive);

        if (hasSensitive) {
            // 如果有敏感内容，添加敏感词提示
            result.setSensitiveWords(Arrays.asList("违规内容"));
            result.setFilteredContent(filterSensitiveContent(originalContent));
        } else {
            result.setSensitiveWords(new ArrayList<>());
            result.setFilteredContent(originalContent);
        }

        return result;
    }

    /**
     * 处理微信API错误
     */
    private SensitiveCheckRespVO handleWxError(WxErrorException e, String content) {
        int errorCode = e.getError().getErrorCode();

        switch (errorCode) {
            case 87014: // 内容含有违法违规内容
                SensitiveCheckRespVO sensitiveResult = new SensitiveCheckRespVO();
                sensitiveResult.setHasSensitive(true);
                sensitiveResult.setSensitiveWords(Arrays.asList("违规内容"));
                sensitiveResult.setFilteredContent(filterSensitiveContent(content));
                return sensitiveResult;

            case 61005: // 系统繁忙，此时请开发者稍候再试
                log.warn("[handleWxError][微信内容安全检查系统繁忙，稍后重试] content: {}", content);
                throw exception(COMMUNITY_SENSITIVE_CHECK_BUSY);

            case 40001: // AppSecret错误或者AppSecret不属于这个小程序
            case 40013: // 不合法的AppID
                log.error("[handleWxError][微信配置错误] errorCode: {}, content: {}", errorCode, content);
                throw exception(COMMUNITY_WX_CONFIG_ERROR);

            case 45009: // 接口调用超过限额
                log.warn("[handleWxError][微信内容安全检查接口调用超过限额] content: {}", content);
                throw exception(COMMUNITY_SENSITIVE_CHECK_BUSY);

            default:
                log.error("[handleWxError][微信内容安全检查未知错误] errorCode: {}, content: {}", errorCode, content);
                // 对于未知错误，为了不影响用户体验，返回安全结果
                return buildSafeResult(content);
        }
    }

    /**
     * 构建安全的检查结果
     */
    private SensitiveCheckRespVO buildSafeResult(String content) {
        SensitiveCheckRespVO result = new SensitiveCheckRespVO();
        result.setHasSensitive(false);
        result.setSensitiveWords(new ArrayList<>());
        result.setFilteredContent(content);
        return result;
    }

    /**
     * 过滤敏感内容
     */
    private String filterSensitiveContent(String content) {
        if (StrUtil.isBlank(content)) {
            return content;
        }
        // 简单的过滤策略：用***替换
        return "***";
    }

    /**
     * 处理异常情况
     */
    private SensitiveCheckRespVO handleException(Exception e, String content) {
        if ("strict".equals(securityConfig.getFailureStrategy())) {
            throw exception(COMMUNITY_SENSITIVE_CHECK_FAILED, e.getMessage());
        } else {
            // 宽松模式：记录日志但允许通过
            log.warn("[handleException][内容安全检查失败，宽松模式允许通过] content: {}, error: {}", content, e.getMessage());
            return buildSafeResult(content);
        }
    }

    /**
     * 下载图片
     */
    private byte[] downloadImage(String imageUrl) {
        try {
            // HttpUtil.downloadBytes 只接受一个参数，不支持超时设置
            return HttpUtil.downloadBytes(imageUrl);
        } catch (Exception e) {
            log.error("[downloadImage][下载图片失败] imageUrl: {}", imageUrl, e);
            throw exception(COMMUNITY_IMAGE_DOWNLOAD_FAILED, imageUrl);
        }
    }

    /**
     * 生成内容的缓存键
     */
    private String generateCacheKey(String content) {
        return DigestUtil.md5Hex(content);
    }

}
